<?php
/**
 *@作者:MissZhang
 *@邮箱:<787727147@qq.com>
 *@创建时间:2022/3/18 9:04 上午
 *@说明:公共请求类
 */

namespace app\api\controller;

require_once root_path('vendor') . "aliyun-dysms-php-sdk-lite/SignatureHelper.php";

use Aliyun\DySDKLite\SignatureHelper;
use app\common\model\TabBar;
use app\common\model\Users;
use app\common\service\PlatFormFactory;
use app\common\service\WechatOfficialService;
use app\common\util\MyException;
use think\facade\Db;
use hg\apidoc\annotation as Apidoc;
use think\Response;
use think\response\Json;

/**
 * @Apidoc\Title("公共请求接口")
 */
class CommonApi extends Base
{
    private $sms = [];//短信配置

    protected function initialize()
    {
        parent::initialize();
        $this->sms = getSysConfig('sms');
    }

    /**
     * @Apidoc\Title("获取验证码")
     * @Apidoc\Method("POST")
     * @Apidoc\url("api/GetCode")
     * @Apidoc\Param("mobile", type="int", require=true, desc="手机号")
     * @Apidoc\Param("scene", type="int",require=true, desc="验证场景")
     */
    public function get_code()
    {
        $mobile = input('mobile');
        $scene = input('scene');//1:修改个人信息 2:注册 3:找回密码 4:修改密码5提现6转赠7转化
        //验证传输手机号是否正确
        if (!check_mobile($mobile)) {
            throw new MyException('手机号码格式有误');
        }
        //验证使用情况
        if (isset($scene) && in_array($scene, [1, 3, 4, 5, 6, 7])) {
            $user = Users::where('mobile', $mobile)->find();
            if (empty($user)) {
                throw new MyException('手机号码未注册');
            }
        }
        //验证使用情况
        if (isset($scene) && $scene == '2') {
            $user = Users::where('mobile', $mobile)->find();
            if (!empty($user)) {
                throw new MyException('手机号码已注册');
            }
        }
        $ab = $this->randstring();//获取随机数字
        //设置存储数据
        $data['scene'] = $scene;
        $data['code'] = $ab;
        $data['mobile'] = $mobile;
        $data['add_time'] = time();
        //验证请求间隔
        $res = Db::name('sms_log')->where(['mobile' => $mobile])->find();
        if ($res) {
            $interval_time = time() - $res['add_time'];
            if ($interval_time < $this->sms['sms_time_out']) {
                throw new MyException('发送太频繁');
            } else {
                $log = Db::name('sms_log')->where('mobile', $mobile)->update($data);
            }
        } else {
            $log = Db::name('sms_log')->insert($data);
        }
        $sms = $this->sendAliSms($ab, $mobile);
        //        $sms=$this->smsbao($mobile,$ab);
        //        if ($log && $sms==0){
        if ($log && $sms->Code == 'OK') {
            throw new MyException('发送成功', 200);
        } else {
            throw new MyException('发送失败');
        }
    }

    /**
     * 短信宝发送短信
     * @param string $mobile 手机号码
     * @param string $code 验证码
     */
    private function smsbao($mobile, $code)
    {
        $statusStr = array(
            "0"  => "短信发送成功",
            "-1" => "参数不全",
            "-2" => "服务器空间不支持,请确认支持curl或者fsocket，联系您的空间商解决或者更换空间！",
            "30" => "密码错误",
            "40" => "账号不存在",
            "41" => "余额不足",
            "42" => "帐户已过期",
            "43" => "IP地址限制",
            "50" => "内容含有敏感词"
        );
        $smsapi = "http://api.smsbao.com/";
        $user = $this->sms['sms_account']; //短信平台帐号
        $pass = md5($this->sms['sms_password']); //短信平台密码
        $content = "【黛洁电商】您的验证码是{$code}。如非本人操作，请忽略本短信";//要发送的短信内容
        //        $content="【睿胜科技工作室】您的验证码是{$code},若非本人操作请忽略此消息。";//要发送的短信内容
        $phone = $mobile;//要发送短信的手机号码
        $sendurl = $smsapi . "sms?u=" . $user . "&p=" . $pass . "&m=" . $phone . "&c=" . urlencode($content);
        $result = file_get_contents($sendurl);
        return $result;
    }

    /**
     * 阿里云发送短信
     * @param string $code 验证码
     * @param string $mobile 手机号码
     */
    private function sendAliSms($code, $mobile)
    {
        // *** 需用户填写部分 ***
        // 必填：是否启用https
        $security = false;
        //必填: 请参阅 https://ak-console.aliyun.com/ 取得您的AK信息
        $accessKeyId = $this->sms['access_key'];
        $accessKeySecret = $this->sms['secret'];
        //必填: 短信接收号码
        $params["PhoneNumbers"] = $mobile;
        //必填: 短信签名，应严格按"签名名称"填写，请参考: https://dysms.console.aliyun.com/dysms.htm#/develop/sign
        $params["SignName"] = $this->sms['sign_name'];
        //必填: 短信模板Code，应严格按"模板CODE"填写, 请参考: https://dysms.console.aliyun.com/dysms.htm#/develop/template
        $params["TemplateCode"] = $this->sms['sms_template'];
        //可选: 设置模板参数, 假如模板中存在变量需要替换则为必填项
        $params['TemplateParam'] = array(
            "code" => $code
        );
        //可选: 设置发送短信流水号
        $params['OutId'] = "12345";
        //可选: 上行短信扩展码, 扩展码字段控制在7位或以下，无特殊需求用户请忽略此字段
        $params['SmsUpExtendCode'] = "1234567";
        // *** 需用户填写部分结束, 以下代码若无必要无需更改 ***
        if (!empty($params["TemplateParam"]) && is_array($params["TemplateParam"])) {
            $params["TemplateParam"] = json_encode($params["TemplateParam"], JSON_UNESCAPED_UNICODE);
        }
        // 初始化SignatureHelper实例用于设置参数，签名以及发送请求
        $helper = new SignatureHelper();
        // 此处可能会抛出异常，注意catch
        $content = $helper->request(
            $accessKeyId,
            $accessKeySecret,
            "dysmsapi.aliyuncs.com",
            array_merge($params, array(
                "RegionId" => "cn-hangzhou",
                "Action"   => "SendSms",
                "Version"  => "2017-05-25",
            )),
            $security
        );
        return $content;
    }

    /**
     * 获取随机位数数字
     * @param integer $len 长度
     * @return string
     */
    private static function randString($len = 6)
    {
        $chars = str_repeat('0123456789', $len);
        $chars = str_shuffle($chars);
        $str = substr($chars, 0, $len);
        return $str;
    }

    /**
     * @Apidoc\Title("获取地区")
     * @Apidoc\Method("POST")
     * @Apidoc\url("api/get_areas")
     * @Apidoc\Param("parent_id", type="int",require=true, desc="上级id")
     */
    public function get_region()
    {
        $parent_id = input('parent_id', 0); // 父id
        $list = Db::name('region')->where('parent_id', $parent_id)->column('id,name');
        throw new MyException('获取成功', 200, ['result' => $list]);
    }

    public function config(PlatFormFactory $platFormFactory)
    {
        $data['appid'] = $platFormFactory->create()->getConfig('appid');
        $data['store_title'] = getSysConfig('basic.store_title');
        $data['wap_login_logo'] = SITE_URL . getSysConfig('basic.wap_login_logo');

        return json($data);
    }

    public function tabBar()
    {
        $list = TabBar::where('status', 1)->select()->map(function ($tabbar) {
            $tabbar->selected_image = request()->domain() . $tabbar->selected_image;
            $tabbar->unselect_image = request()->domain() . $tabbar->unselect_image;
            return $tabbar;
        });

        return json($list);
    }

    /**
     * @param \app\common\service\WechatOfficialService $officialService
     * @return \think\response\Json
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
     * @throws \EasyWeChat\Kernel\Exceptions\RuntimeException
     * @throws \Psr\SimpleCache\InvalidArgumentException
     */
    public function officialConfig(WechatOfficialService $officialService): Json
    {
        $apis = $this->request->post('apis/a');
        $debug = $this->request->post('debug/b', false);
        $url = $this->request->post('url');

        return json($officialService->buildConfig($apis, $url, $debug));
    }

    /**小程序码
     * @param \app\common\service\PlatFormFactory $platFormFactory
     * @return \think\Response
     * @throws \GuzzleHttp\Exception\GuzzleException
     * @throws \Throwable
     */
    public function qrcode(PlatFormFactory $platFormFactory): Response
    {
        $this->validate(request()->param(), [
            'path'  => 'require',
            'scene' => 'require',
        ]);

        $platform = $platFormFactory->create();

        $path = $this->request->param('path');
        $scene = $this->request->param('scene');

        $result = $platform->qrcode($path, $scene);
        return response($result, 200, ['Content-Length' => strlen($result), 'Content-Type' => 'image/png']);
    }
}
